package com.atguigu.serviceBash;

import com.atguigu.utils.R;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
 * 全局异常处理
 *
 * @author zy
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 自定义异常类
     *
     * @param e e
     * @return R
     */
    @ExceptionHandler(value = GlobalException.class)
    @ResponseBody
    public R nullError(GlobalException e) {
        return R.error().message(e.getMessage()).code(20001);
    }

    /**
     * JSR380 参数校验异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) {
        StringBuilder errorInfo = new StringBuilder();
        BindingResult bindingResult = exception.getBindingResult();
        for (int i = 0; i < bindingResult.getFieldErrors().size(); i++) {
            if (i > 0) {
                errorInfo.append(",");
            }
            FieldError fieldError = bindingResult.getFieldErrors().get(i);
            errorInfo.append(fieldError.getField()).append(" :").append(fieldError.getDefaultMessage());
        }

        //返回BaseResponse
        return R.error(500, errorInfo.toString());
    }


    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R handleConstraintViolationException(ConstraintViolationException exception) {
        StringBuilder errorInfo = new StringBuilder();
        String errorMessage;

        Set<ConstraintViolation<?>> violations = exception.getConstraintViolations();
        for (ConstraintViolation<?> item : violations) {
            errorInfo.append(item.getMessage()).append(",");
        }
        errorMessage = errorInfo.toString().substring(0, errorInfo.toString().length() - 1);

        return R.error(500, errorInfo.toString());
    }

    /**
     * 全局异常从上到下依次匹配执行
     *
     * @param var var
     * @return R
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public R error(Exception var) {
        var.printStackTrace();
        return R.error().message("异常为：" + var.getMessage()).code(20001);
    }
}
